<template>
  <div class="card">
    <el-link class="back" @click="handleBack"><el-icon><Back /></el-icon>返回 </el-link>
    <div class="detail-box">
      <div class="detail-left">
        <div class="box">
          <p class="title"> <img width="18" class="middle" src="@/assets/images/upload.png" alt="" /> <span class="middle">上传规范</span></p>
          <p>规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档规范文档</p>
        </div>
        <div class="box">
          <p class="title"><img width="22" class="middle" src="@/assets/images/pic.png" alt="" /> <span class="middle">数据上传</span></p>
          <div class="pic-box">
            <el-upload
              accept=".jpg,.jpeg,.png,.gif"
              class="uploader"
              action="#"
              v-model:file-list="fileList"
              limit="5"
              list-type="picture-card"
              :on-preview="handlePreview"
              :on-remove="handleRemove"
              :before-upload="(file) => beforeUpload(file)"
              :on-exceed="handleExceed"
            >
              <el-icon><Plus /></el-icon>
              <template #tip>
                <div class="el-upload__tip">
                  最多上传5张图片
                </div>
              </template>
            </el-upload>
          </div>
        </div>
        <el-button class="btn" @click="handleGenerate">一键生成&nbsp; &nbsp;<img width="30" class="middle" src="@/assets/images/icon-logo.png" alt=""> 34</el-button>
      </div>
      <div class="detail-right">
        <p class="title"><img width="18" class="middle" src="@/assets/images/folder.png" alt="" /> <span class="middle">生成结果</span></p>
        <div class="loading" v-if="loading">
          <div class="progress">
            <div class="bar"></div>
          </div>
          <p class="tip">正在构建模型…</p>
        </div>
        <div class="empty" v-else-if="list.length === 0">
          <img src="@/assets/images/empty.png" alt="">
          <p class="name">暂无数据</p>
          <p class="tip">快去上传你的图片吧</p>
        </div>
        <template v-else>
          <ul class="list">
            <motion.li 
              v-for="(item, index) in list" :key="index"
              :initial="{ opacity: 0, y: 20 }"
              :animate="{ opacity: 1, y: 0 }"
              :transition="{ duration: 0.3, delay: index * 0.1 }"
            >
              <img :src="item" alt="">
            </motion.li>
          </ul>
          <div style="text-align: center;">
            <el-button round style="padding: 20px 120px;font-size: 16px;">
              <el-icon :size="20"><Download /></el-icon>下载
            </el-button>
          </div>
        </template>
      </div>
    </div>
    <el-dialog class="common-dialog" width="80%" v-model="showDialog" @close="handleDialogCancel">
      <div v-if="pendingFile">
        <div class="preview-box">
          <cropper
            ref="cropperRef"
            :class="['cropper', disabled ? 'disabled' : '']"
            :src="imageSrc"
            :default-position="{ left: 0, top: 0 }"
            :default-size="{ width: 150, height: 150 }"
            :resize-image="false"
            @change="handleCropperChange"
          />
        </div>
      </div>
      <template #header>
        <i class="line"></i>
        <i class="line"></i>
        <p class="title">上传图片</p>
      </template>
      <template #footer>
        <div class="footer-box">
          <div class="oper">
            <el-button size="large" @click="selectCrop"><i class="icon-select"></i> 选择区域</el-button>
            <el-button size="large" :disabled="disabled" @click="resetCrop"><i class="icon-undo"></i> 撤销</el-button>
          </div>
          <div class="btn">
            <el-button size="large" @click="handleDialogCancel">取 消</el-button>
            <el-button size="large" type="primary" @click="handleDialogConfirm">确 定</el-button>
          </div>
      </div>
      </template>
    </el-dialog>
    <el-image-viewer
      v-if="showViewer" 
      :url-list="previewList"
      :initial-index="previewIndex"
      @close="showViewer = false"
    />
  </div>
  <RiskDialog ref="riskDialogRef" @confirm="confirmRisk"/>
</template>
<script setup>
import { motion } from "motion-v"
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import RiskDialog from './components/RiskDialog.vue'
import { Plus } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import html2canvas from 'html2canvas'
import { Cropper } from 'vue-advanced-cropper'
import 'vue-advanced-cropper/dist/style.css'
const riskDialogRef = ref(null)
const imageSrc = ref('');
const fileList = ref([])
const showDialog = ref(false)
const pendingFile = ref(null)
const disabled = ref(true)
const cropperRef = ref(null)
const showViewer = ref(false)
const previewList = ref([])
const previewIndex = ref(0)
const loading = ref(false)
const list = ref(['https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100', 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'])
const router = useRouter()
const handleBack = () => {
  router.back()
}
const handleExceed = () => {
  ElMessage.error('最多只能上传5张图片')
}
const beforeUpload = (file) => {
  pendingFile.value = file
  imageSrc.value = window.URL.createObjectURL(file);
  showDialog.value = true
  return false
}
const handlePreview = (file) => {
  showViewer.value = true
  previewList.value = fileList.value.map(item => item.url)
  previewIndex.value = fileList.value.indexOf(file)
}
const handleRemove = (file) => {
  console.log(file)
}
const handleCropperChange = (result) => {
  console.log("🚀 ~ handleCropperChange ~ result:", result)
}
// 选择区域
const selectCrop = () => {
  disabled.value = false
}
// 获取裁剪坐标
const getCropData = () => {
  const { coordinates: coords } = cropperRef.value.getResult()
  return [{
    左上: { x: coords.left, y: coords.top },
    右上: { x: coords.left + coords.width, y: coords.top },
    左下: { x: coords.left, y: coords.top + coords.height },
    右下: { x: coords.left + coords.width, y: coords.top + coords.height }
  }]
  // 获取Base64格式
  // const base64 = canvas.toDataURL('image/jpeg', 0.9)
  // console.log('Base64结果:', base64)
  
  // // 获取Blob对象
  // canvas.toBlob((blob) => {
  //   console.log('Blob对象:', blob)
  // }, 'image/jpeg', 0.9)
}
// 撤销
const resetCrop = () => {
  if (cropperRef.value) cropperRef.value.reset()
  disabled.value = true
  if (document.querySelector('.crop-overlay')) document.querySelector('.crop-overlay').remove()
}
// 取消
const handleDialogCancel = () => {
  if (document.querySelector('.crop-overlay')) document.querySelector('.crop-overlay').remove()
  showDialog.value = false
  resetCrop()
}
// 确定
const handleDialogConfirm = async () => {
  const imgData = { name: pendingFile.value.name, url: imageSrc.value }
  if(!disabled.value){
    const coordinates = getCropData()
    imgData.coordinates = coordinates
    if (document.querySelector('.cropper')) {
      const image = document.querySelector('.vue-advanced-cropper__image')
      const computedStyle = window.getComputedStyle(image)
      const transformMatrix = computedStyle.transform.split(',')
      const scale = parseFloat(transformMatrix[3]) || 0
      const x = parseFloat(transformMatrix[4]) || 0
      const y = parseFloat(transformMatrix[5]) || 0
      const params = {}
      if(scale <= 1) {
        params.x = x;
        params.y = y;
        params.width = parseInt(computedStyle.width);
        params.height = parseInt(computedStyle.height)
      }
      const canvas = await html2canvas(document.querySelector('.cropper'), params);
      const dataUrl = canvas.toDataURL('image/png');
      imgData.url = dataUrl
    }
  }
  fileList.value.push(imgData)
  pendingFile.value = null
  handleDialogCancel()
}
// 生成
const isFengxian = false
const handleGenerate = () => {
  if(fileList.value.length === 0){
    ElMessage.error('请先上传图片')
    return
  }
  if (isFengxian){
    uploadDialog()
  }else {
    riskDialogRef.value.open()
  }
}

const confirmRisk = () => {
  uploadDialog()
}
const uploadDialog = () => {
  console.log('fileList', fileList.value)
  loading.value = true
  setTimeout(() => {
    loading.value = false
    list.value = fileList.value.map(item => item.url)
  }, 3000)
}
</script>
<style lang="scss" scoped>
.back {
  font-size: 20px;
  margin-bottom: 20px;
}
.detail-box{
  display: flex;
  justify-content: space-between;
  margin-bottom: 30px;
  .title{
    font-size: 20px;
    font-weight: bold;
    margin-bottom: 10px;
    color: #333;
  }
  .desc{
    font-size: 20px;
    font-weight: bold;
    color: #333;
    margin-bottom: 20px;
  }
  .detail-left{
    width: 30%;
    min-width: 340px;
    padding-right: 20px;
    margin-right: 20px;
    border-right: 1px solid #E0E0E0;
    position: relative;
    padding-bottom: 200px;
    .box{
      background: #F3F5F9;
      border-radius: 5px;
      padding: 20px;
      margin-bottom: 20px;
      color: #333;
      min-height: 250px;
      .title{
        border-bottom: 1px solid #E0E0E0;
        padding-bottom: 10px;
        margin-bottom: 10px;
      }
      .btn-box{
        text-align: center;
        padding: 25px 20px;
        .el-button{
          width: 60%;
          color: #333;
          border-radius: 40px;
          height: 54px;
          font-size: 18px;
        }
      }
      .info{
        color: rgba(0,10,32,0.85);
      }
    }
    .btn{
      font-size: max(1.5vw, 20px);
      color: #fff;
      padding: max(2vw, 26px) 0;
      background-image: linear-gradient(99deg, #2462F1 0%, #3C2CDC 100%);
      border: 3px solid rgba(47,84,235,1);
      border-radius: 41px;
      width: calc(100% - 20px);
      position: absolute;
      bottom: 0;
      left: 0;
      &::before,
      &::after{
        content: '';
        width: 92%;
        height: 14px;
        border-radius: 40px;
        position: absolute;
        top: 2px;
        left: 4%;
        background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, rgba(255, 255, 255, 0) 100%);
      }
      &::after{
        top: inherit;
        bottom: 2px;
        background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
      }
      &:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 20px rgba(36, 98, 241, 0.3);
        transition: all 0.3s ease;
      }
    }
  }
  .detail-right{
    width: 70%;
    
  }
}
.loading{
  width: 100%;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  margin-top: 200px;
  .tip{
    color: #333;
    margin-top: 20px;
  }
  .progress {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    position: relative;
    z-index: 1;
    height: 1.25rem;
    width: 500px;
    border-radius: 20px;
    outline: 1.5px solid #6a6a6b;
    border: 2px solid transparent;
    overflow: hidden;
    transition: all 125ms ease;
    animation: outline 4s ease infinite;
    background-color: white;
    &::before {
      content: "";
      position: absolute;
      font-weight: 600;
      font-size: 14px;
      z-index: 9;
      animation: colors 4s ease infinite;
    }

    .bar {
      position: absolute;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      transform-origin: left center;
      animation: progress 4s ease infinite;
      
      &::before {
        content: "";
        position: absolute;
        inset: 0;
        height: 100%;
        width: 100%;
        border-radius: 20px;
        transform-origin: left center;
        transition: all 125ms ease;
        background-size: 1.25rem 1.25rem;
        box-shadow:
          inset 0.3rem 0.3rem 0.6rem #ffffff8f,
          inset -0.2rem -0.2rem 0.5rem #77777777;
        background-image: linear-gradient(
          45deg,
          #cccccc33 25%,
          transparent 0,
          transparent 50%,
          #cccccc33 0,
          #cccccc33 75%,
          transparent 0,
          transparent
        );
        animation: bar 1s linear infinite;
      }
      &::after {
        content: "";
        inset: 0;
        height: 100%;
        width: 100%;
        border-radius: 20px;
        background-color: var(--progress-color);
        background: linear-gradient(90deg, #3C2CDC 0%, #2462F1 100%);
      }
    }

    @keyframes outline {
      from {
        outline-color: #fff;
      }
      50% {
        outline-color: #3C2CDC;
      }
      to {
        outline-color: #2462F1;
      }
    }
    @keyframes colors {
      from {
        color: #000;
      }
      to {
        color: #fff;
      }
    }
    @keyframes progress {
      from {
        transform: translateX(-100%);
      }
      to {
        transform: translateX(0%);
      }
    }
    @keyframes bar {
      from {
        background-position: 0 0;
      }
      to {
        background-position: 2.5rem 0;
      }
    }
  }
}
.uploader{
  :deep(.el-upload-list){
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    .el-upload,
    .el-upload-list__item{
      width: max(5vw, 80px);
      height: max(5vw, 80px);
      margin: 0;
    }
  }
}
.common-dialog{
  .preview-box{
    padding: 20px;
    max-height: 500px;
    overflow: auto;
    font-size: 0;
  }
}
:deep(.cropper){
  &.disabled{
    .vue-rectangle-stencil{
      display: none;
    }
    .vue-advanced-cropper__background, 
    .vue-advanced-cropper__foreground{
      background: #fff;
      opacity: 0;
    }
  }
  // .vue-advanced-cropper__background,
  // .vue-advanced-cropper__foreground{
  //   background: #fff;
  //   opacity: 0;
  // }
  // .vue-advanced-cropper__foreground{
  //   background: #fff;
  //   opacity: 0.5;
  // }
}
.list{
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 100px;
  li{
    width: 210px;
    height: 250px;
    border-radius: 5px;
    overflow: hidden;
    border: 1px solid #E0E0E0;
    img{
      width: 100%;
      height: 100%;
      object-fit: contain;
      transition: transform 0.3s;
    }
    &:hover img {
      transform: scale(1.1);
    }
  }
}
</style>